# 一共有7个代码文件，每个文件对应一个最能体现的原则，请找出每个原则对应的代码文件，然后分析该代码文件是如何体现该原则的。

# 请将文件名修改为相应的原则名称，如：1.单一职责原则.py。并回答以下问题。然后将代码文件上传到之前实验创建的码云仓库中。
# 将码云代码仓库里新建文件夹code_snippets，将代码文件放入该文件夹中。

# 1.运行代码
# 输出如下：
# 图书《算法导论》已借出。  
# 为用户 101 生成借阅记录：图书 B1001  
# 用户 Alice 已成功借阅图书 B1001  
# 用户 Bob 没有借阅权限。  
# 图书《B1001》已归还。
# 2. 指出该代码体现了哪个原则
# 体现了迪米特法则

# 3. 请说明该代码是如何体现该原则
# 迪米特法则，又称最少知道原则，指一个对象应该对其他对象有最少的了解。
# 它强调只与直接的朋友通信，而“直接的朋友”通常指的是：当前对象本身、当前对象的成员对象、当前对象的方法参数对象，以及当前对象所创建或管理的对象。
# 代码通过封装内部细节、减少依赖、控制访问和降低耦合来体现迪米特法则。
# 图书类，负责图书相关的信息
class Book:
    def __init__(self, book_id, title):
        self.book_id = book_id
        self.title = title
        self.is_available = True

    def is_borrowable(self):
        return self.is_available

    def borrow(self):
        self.is_available = False
        print(f"图书《{self.title}》已借出。")

    def return_book(self):
        self.is_available = True
        print(f"图书《{self.title}》已归还。")

# 库存系统类，负责库存管理
class Inventory:
    def __init__(self):
        self.books = {}

    def add_book(self, book: Book):
        self.books[book.book_id] = book

    def is_book_available(self, book_id):
        return self.books.get(book_id) and self.books[book_id].is_borrowable()

    def borrow_book(self, book_id):
        if self.is_book_available(book_id):
            self.books[book_id].borrow()
        else:
            print(f"图书 {book_id} 不可借阅或不存在。")

    def return_book(self, book_id):
        if book_id in self.books:
            self.books[book_id].return_book()
        else:
            print(f"图书 {book_id} 不存在。")

# 权限系统类，负责检查用户权限
class PermissionSystem:
    def check_permission(self, user):
        # 简单检查权限
        return user.has_permission()

# 用户账户类，模拟用户的权限检查
class UserAccount:
    def __init__(self, user_id, name, permission_level):
        self.user_id = user_id
        self.name = name
        self.permission_level = permission_level

    def has_permission(self):
        # 简单的权限检查
        return self.permission_level >= 1

# 借阅记录系统类，负责生成借阅记录
class BorrowingRecordSystem:
    def create_borrowing_record(self, user_id, book_id):
        print(f"为用户 {user_id} 生成借阅记录：图书 {book_id}")

# 图书管理系统类，遵循迪米特法则
class LibraryManagementSystem:
    def __init__(self, inventory: Inventory, permission_system: PermissionSystem, borrowing_record_system: BorrowingRecordSystem):
        self.inventory = inventory
        self.permission_system = permission_system
        self.borrowing_record_system = borrowing_record_system

    def borrow_book(self, user: UserAccount, book_id):
        # 用户不直接和库存系统或权限系统交互，图书管理系统处理这些细节
        if self.permission_system.check_permission(user):
            if self.inventory.is_book_available(book_id):
                self.inventory.borrow_book(book_id)
                self.borrowing_record_system.create_borrowing_record(user.user_id, book_id)
                print(f"用户 {user.name} 已成功借阅图书 {book_id}")
            else:
                print(f"图书 {book_id} 不可借阅或不存在。")
        else:
            print(f"用户 {user.name} 没有借阅权限。")

    def return_book(self, book_id):
        self.inventory.return_book(book_id)

# 测试示例
if __name__ == "__main__":
    # 初始化系统组件
    inventory = Inventory()
    permission_system = PermissionSystem()
    borrowing_record_system = BorrowingRecordSystem()

    # 添加图书
    book1 = Book("B1001", "算法导论")
    book2 = Book("B1002", "机器学习")
    inventory.add_book(book1)
    inventory.add_book(book2)

    # 初始化图书管理系统
    library_system = LibraryManagementSystem(inventory, permission_system, borrowing_record_system)

    # 创建用户
    user1 = UserAccount(user_id=101, name="Alice", permission_level=1)
    user2 = UserAccount(user_id=102, name="Bob", permission_level=0)

    # 用户借书
    library_system.borrow_book(user1, "B1001")
    library_system.borrow_book(user2, "B1002")

    # 用户还书
    library_system.return_book("B1001")
